package com.muse.ribbon.controller;

import java.net.URI;
import java.util.List;
import java.util.Random;

import javax.annotation.Resource;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import lombok.extern.slf4j.Slf4j;

/**
 * @description
 * @author: muse
 * @create: 2021-08-17 21:51
 **/
@Slf4j
@RequestMapping("/consumer")
@RestController
public class ConsumerController {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private DiscoveryClient discoveryClient;

    @Resource
    private LoadBalancerClient loadBalancerClient;

    /**
     * 使用new的RestTemplate（http://localhost:7002/consumer/restTemplateTest）
     */
    @GetMapping("/restTemplateTest")
    public String restTemplateTest() {
        log.info("restTemplateTest invoke!");
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject("http://localhost:7000/provider/hello", String.class);
    }

    /**
     * 使用Bean的RestTemplate（http://localhost:7002/consumer/restTemplateTestUseBean）
     */
    @GetMapping("/restTemplateTestUseBean")
    public String restTemplateTestUseBean() {
        log.info("restTemplateTestUseBean invoke!");
        return restTemplate.getForObject("http://localhost:7000/provider/hello", String.class);
    }

    /**
     * 使用DiscoveryClient获取服务列表进行随机服务调用（http://localhost:7002/consumer/discoveryClient）
     * 【注意】不能加@LoadBalanced，否则请求失败
     */
    @GetMapping("/discoveryClient")
    public String discoveryClient() {
        log.info("discoveryClient invoke!");
        // 获得服务id下的服务信息
        List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("ribbon-producer");
        serviceInstanceList.forEach(serviceInstance -> log.info("host={}, port={}, uri={}", serviceInstance.getHost()
                , serviceInstance.getPort(), serviceInstance.getUri()));

        int num = new Random().nextInt(serviceInstanceList.size());
        URI uri = serviceInstanceList.get(num).getUri();
        log.info("num={}, uri={}", num, uri);
        return restTemplate.getForObject( uri + "/provider/hello", String.class);
    }

    /**
     * 使用LoadBalancerClient自带的负载均衡功能执行服务调用（http://localhost:7002/consumer/loadBalancerClient）
     * 【注意】不能加@LoadBalanced，否则请求失败
     */
    @GetMapping("/loadBalancerClient")
    public String loadBalancerClient() {
        log.info("loadBalancerClient invoke!");
        // 获得负载均衡实例
        ServiceInstance serviceInstance = loadBalancerClient.choose("ribbon-producer");
        log.info("uri={}", serviceInstance.getUri());
        return restTemplate.getForObject( serviceInstance.getUri() + "/provider/hello", String.class);
    }

    /**
     * 使用@LoadBalanced修饰的RestTemplate来执行具有负载均衡功能的服务调用（http://localhost:7002/consumer/loadBalancerAnnotation）
     */
    @GetMapping("/loadBalancerAnnotation")
    public String loadBalancerAnnotation() {
        log.info("loadBalancerAnnotation invoke!");
        // 获得负载均衡实例
        return restTemplate.getForObject("http://ribbon-producer/provider/hello", String.class);
    }


}
